# 单例模式 (Singleton Pattern)
# 单例模式是一种创建型设计模式，它保证一个类只有一个实例，并提供一个全局访问点。

print("=== 单例模式示例 ===\n")

# 1. 使用 __new__ 方法实现单例模式
class Singleton:
    """使用 __new__ 方法实现单例模式"""
    _instance = None  # 类变量，用于存储实例
    
    def __new__(cls):

        if cls._instance is None:
            # super().__new__(cls) 调用的是 object.__new__(cls)
            # 在 Python 中，如果您没有显式指定父类，那么类会默认继承自 object 类。
            print("调用 object.__new__ 创建新实例")
            cls._instance = super().__new__(cls)
            print("创建新的 Singleton 实例")
        else:
            print("返回已存在的 Singleton 实例")
        return cls._instance
    
    def __init__(self):
        # 为了避免重复初始化，可以使用一个标志位
        if not hasattr(self, 'initialized'):
            print("初始化 Singleton 实例")
            self.initialized = True

# 测试 __new__ 方法实现的单例
print("1. 使用 __new__ 方法实现单例模式:")
print("类的继承关系:")
print(f"Singleton.__bases__: {Singleton.__bases__}")  # 显示父类
print(f"object 类: {object}")
print()

s1 = Singleton()
s2 = Singleton()
print(f"s1 is s2: {s1 is s2}")  # True，表示是同一个实例
print(f"s1 id: {id(s1)}")
print(f"s2 id: {id(s2)}")
print()

# 2. 使用装饰器实现单例模式
def singleton(cls):
    """单例装饰器"""
    instances = {}  # 字典存储类的实例
    
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
            print(f"创建新的 {cls.__name__} 实例")
        else:
            print(f"返回已存在的 {cls.__name__} 实例")
        return instances[cls]
    
    return get_instance

@singleton
class DatabaseConnection:
    """数据库连接类"""
    def __init__(self):
        print("初始化数据库连接")
        self.connection = "数据库连接对象"

# 测试装饰器实现的单例
print("2. 使用装饰器实现单例模式:")
db1 = DatabaseConnection()
db2 = DatabaseConnection()
print(f"db1 is db2: {db1 is db2}")  # True
print()

# 3. 使用模块实现单例模式
# Python 的模块天然就是单例的，因为模块只会被导入一次
print("3. 使用模块实现单例模式:")
print("创建一个模块文件，例如 config.py，其中定义配置对象")
print("在其他文件中多次导入该模块，得到的都是同一个模块对象")
print()



# 4. 单例模式的应用场景
print("=== 单例模式的应用场景 ===")
applications = [
    "1. 配置管理器 - 整个应用程序中只需要一个配置对象",
    "2. 日志记录器 - 整个应用程序共享一个日志实例",
    "3. 数据库连接池 - 避免创建多个连接池",
    "4. 缓存管理器 - 全局缓存对象",
    "5. 线程池 - 全局线程管理",
]

for app in applications:
    print(app)

print()

# 5. 单例模式的优缺点
print("=== 单例模式的优缺点 ===")
print("优点:")
print("1. 内存中只有一个实例，节省内存")
print("2. 全局访问点，方便访问")
print("3. 允许对实例化过程进行控制")

print("\n缺点:")
print("1. 违反单一职责原则")
print("2. 难以进行单元测试")
print("3. 可能导致内存泄漏")
print("4. 在多线程环境中需要特殊处理")
print("5. 扩展困难")

print("\n=== 单例模式总结 ===")
print("单例模式确保一个类只有一个实例，并提供全局访问点。")
print("虽然在某些场景下很有用，但需要谨慎使用，避免滥用。")